package base.annotation_demo.demo_03;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * 通过注解 Bean的方式代替读取Bean配置文件的方式演示：
 * 配置文件方式类似这样的：
 * Properties properties = new Properties();
 * ClassLoader loader = ReflectionTest.class.getClassLoader();
 * InputStream in = loader.getResourceAsString(xxx.properties);
 * properties.load(in);
 *
 * String className = properties.getProperty("className");
 * String methodName = properties.getProperty("methodName");
 *
 */
public class ReflectionTest {
    public static void main(String[] args) throws Exception {
        Class<EmpConfig> clazz = EmpConfig.class;
        /**
         * 下面这句,就是在内存中生成了一个该注解接口的子类实现对象
         * class BeanConfigAnnotationImpl implements BeanConfigAnnotation {
         *
         *     @Override
         *     public String className() {
         *         return "base.annotation_demo.demo_03.EmpConfig";
         *     }
         *
         *     @Override
         *     public String methodName() {
         *         return "show";
         *     }
         * }
         */
        BeanConfigAnnotation annotation = clazz.getDeclaredAnnotation(BeanConfigAnnotation.class);

        String className = annotation.className();
        String methodName = annotation.methodName();

        // 加载 className代表的类进内存
        Class<Emp> reflectClass = (Class<Emp>) Class.forName(className);
        // 创建类对象
//        reflectClass.newInstance();
        Constructor<Emp> constructor = reflectClass.getDeclaredConstructor(int.class, String.class, int.class);
        Emp zhangSan = constructor.newInstance(1, "ZhangSan", 18);

        // 获取方法对应的 Method对象，并传入入参类型
        Method method = reflectClass.getDeclaredMethod(methodName, null);

        // 调用对象 zhangSan的method方法，并传入入参值，返回方法执行结果值
        Object invoke = method.invoke(zhangSan, null);
    }
}
